
#ifndef MACROS_H
#define MACROS_H 1

#define debug	0
#define V5	-1
#define V6	-1

#define fg_cfg		-1
#define fg_pe		-1
#define fg_dosx		-1
#define fg_cvpack	V6

#define _PRODUCT	12

#define fg_xref		-1
#define fg_cv		-1
#define fg_segm		-1
#define fg_ai		0
#define fg_rat		0
#define fg_ov		0		// SINGLE-LEVEL OVERLAYS
#define fg_rom		0		// ROM-LINK
#define fg_def		-1		// HAS A DEF FILE
#define fg_slrpack	-1
#define fg_plink	0
#define fg_mscmd	-1
#define fg_implib	0
#define fg_phar		-1
#define fg_winpack	-1
#define fg_dospack	0

#define fgh_prot	-1
#define fgh_dpmi	0
#define fgh_win		0
#define fgh_win32	-1
#define fgh_win32dll	0
#define fgh_dosx	0
#define fgh_inthreads	-1
#define fgh_outhreads	0		// OUTPUT THREADS
#define fgh_mapthread	-1
#define fg_virt		0
#define fg_sym_virt	0
#define page_size	16K
#define PAGE_SIZE	(16*1024)
#define PAGE_SHIFT	2
#define PAGE_BITS	14
#define PAGE_POWER	14
#define PAGE_MASK	0x3FFF
#define fg_td		0

#define fgh_anythreads	(fgh_inthreads || fgh_outhreads || fgh_mapthread)

#define INBUF_LEN		1024
#define SYMBOL_TEXT_SIZE	(8 * 1024)
#define NFN_TEXT_SIZE		320
#define LONG_OMF_DELTA		3

#define APPTYPE		0x8000	// 0=PROGRAM, 1=DLL
//#define APP??		0x4000	// UNKNOWN
#define APPERRORS	0x2000	// ERRORS DURING LINK
//#define APP???		0x1C00	// UNKNOWN
//#define APPWINFLAGS	0x300 // WINDOWAPI, WINDOWCOMPAT, NOTWINDOWCOMPAT
#define APPFLOATS	0x80	// FLOATS USED?
#define APP386		0x40	// 386 INSTRUCTIONS
#define APP286		0x20	// 286 INSTRUCTIONS
#define APP86		0x10	// 8086-ONLY
#define APPPROT		8	// PROTMODE APP
#define APPINSTANCE	4 	// INSTANCE DATA
#define APPMULTI	2	// MULTIPLE DATA (NONSHARED)
#define APPSOLO		1	// SOLO DATA (SHARED)

#define CASE_SENSITIVE	0
#define MAX_RECORD_LEN	(1024+64+6*1024)	// FOR BORLAND
#define SLRIB		0		// NOT OPTLIB
#define OPTLIB		0

#define MAX_LEDATA_LEN	(2*1024)

#define BLOCK_BASE	8		// STARTING OFFSET FOR FAR BLOCKS (FIRST DWORD IS USAGE COUNT, NEXT IS NEXT_PTR)
					// **** FARCALLTRANSLATE MAY NOT HANDLE CHANGE CORECTLY ****

#define EMS_XMS_DELTA	(1024/(PAGE_SIZE/(1024))*2)

#define N_R_THREADS	4	// # of open-read threads
#define N_W_THREADS	4

typedef struct GLOBALSEM_STRUCT
{
    void *_SEM_ITSELF;
    int _SEM_COUNTER;
} GLOBALSEM_STRUCT;

typedef struct ALLOCS_STRUCT
{
    void **ALLO_LAST_LIST;	// LAST STORED LIST OF BLOCKS
    void *ALLO_PTR;		// LOGICAL PTR TO NEXT AVAILABLE BYTE
    unsigned ALLO_CNT;		// BYTES LEFT THIS BLOCK
    int ALLO_SUB_CNT;
    void *ALLO_SUB_PTR;
    void **ALLO_NEXT_BLK;	// PTR TO STORE NEXT BLOCK LOCALLY
    void *ALLO_HASH_TABLE_PTR;	// HASH TABLE IF IT EXISTS
    unsigned ALLO_HASH;		// HASH IF IT EXISTS
    int ALLO_BLK_CNT;		// ALLOCATED BLOCK COUNT
    void *ALLO_BLK_LIST[8];	// LIST OF UP TO 8 ALLOCATED BLOCKS
} ALLOCS_STRUCT;

#define SEQ_TABLE_MAX	(32*32*1024/PAGE_SIZE*4)

typedef struct SEQ_STRUCT
{

    unsigned _SEQ_PTR;		// NEXT ADDRESS TO WRITE TO
    unsigned _SEQ_TABLE[SEQ_TABLE_MAX]; // 256K MAX DATA THIS TYPE, checked in subs/storeseq.asm
    unsigned _SEQ_TARGET;		// PTR TO NEXEHEADER OFFSET OF OFFSET...
    unsigned _SEQ_NEXT_TARGET;
} SEQ_STRUCT;


typedef struct DTA_STRUCT
{
    unsigned short FDATECREATION;
    unsigned short FTIMECREATION;
    unsigned short FDATELASTACCESS;
    unsigned short FTIMELASTACCESS;
    unsigned short FDATELASTWRITE;
    unsigned short FTIMELASTWRITE;
    unsigned CBFILE;
    unsigned CBFILEALLOC;
    unsigned short ATTRFILE;
    unsigned char CCHNAME;
    unsigned char ACHNAME[13];
} DTA_STRUCT;

typedef struct CMDLINE_STRUCT
{
    int (*CMD_SELECTED)();	// USE SRCNAM (NZ) OR NUL
    unsigned char *CMD_EXTENT;	// DEFAULT EXTENT
#if fg_mscmd
    int (*CMD_DESIRED)();	// WANT AT ALL?  LIKE OUTPUT LIBRARY NAME
    unsigned char *CMD_PMSG;	// PROMPT MESSAGE
#endif
} CMDLINE_STRUCT;

#if PAGE_SIZE == 16 * 1024
#define PAGE_SIZE_4_HASH	0xFFD
#define PAGE_SIZE_8_HASH	0x7F7
#define SMALL_TEXT_HASH 	0xffd	//PRIME?????
#define SMALL_SYM_HASH		0xFFD	//1fffh	;0ffdh	;PRIME?????
#define SMALL_RAINBOW_HASH	0xffd	//PRIME?????
#elif PAGE_SIZE == 8 * 1024
#define PAGE_SIZE_4_HASH	0x7F7
#define PAGE_SIZE_8_HASH	0x3FD
//#define SMALL_TEXT_HASH 	0x7F7
#define SMALL_SYM_HASH		0xffd	//7F7H
//#define SMALL_RAINBOW_HASH	0x7F7
#else
#error mistake
#endif


typedef struct STD_PTR_S	// USED BY LIBRARIES, SOON MASTER GROUPS, SEGMENTS, CLASSES, POSSIBLY EVEN SYMBOLS, OTHERS
{
    void *_STD_BASE_NEXT;	// NEXT PLACE TO STORE BLOCK POINTER
    void *_STD_NEXT;		// NEXT PLACE TO STORE PTR
    int _STD_LIMIT;		// # OF VALID ENTRIES IN TABLE
    int _STD_COUNT;		// # LEFT TO ALLOCATE THIS BLOCK
    void (*_STD_ALLOC_ROUTINE)();	// ALLOCATE MEMORY FOR PTRS
    int _STD_TYPE_TEXT;
    void (*_STD_INSTALL_ROUTINE)();	// INSTALL NEXT ENTRY INTO TABLE
    void (*_STD_INSTALL_RANDOM_ROUTINE)();
    void (*_STD_AX_TO_DSSI)();		// CONVERT AX TO PTR IN DS:SI PHYSICAL
    void (*_STD_AX_TO_ESDI)();		// CONVERT AX TO PTR IN ES:DI PHYSICAL
    int _STD_EAX_TO_EBX;
    void *_STD_PTRS[16];	// INITIALLY PTRS, THEN PTRS TO BLOCKS, THEN PTR TO MASTER BLOCK
} STD_PTR_S;

typedef struct FA_BASE_S
{
    unsigned usage_count;
    struct FA_BASE_S *next_ptr;
} FA_BASE_S;

typedef struct FA_S
{
    void *FA_PTR;
    unsigned FA_CNT;
    FA_BASE_S *FA_BASE;
} FA_S;

#define GMEM_FIXED		0x0000
#define GMEM_MOVEABLE		0x0002
#define GMEM_ZEROINIT		0x0040
#define GMEM_NOCOMPACT		0x0010
#define GMEM_NODISCARD		0x0020
#define GMEM_MODIFY		0x0080
#define GMEM_DISCARDABLE 	0x0100
#define GMEM_NOT_BANKED		0x1000
#define GMEM_SHARE		0x2000
#define GMEM_DDESHARE		0x2000
#define GMEM_NOTIFY		0x4000
#define GMEM_LOWER		GMEM_NOT_BANKED


#define INBUF_LEN			1024
#define SYMBOL_TEXT_SIZE		(8 * 1024)
#define NFN_TEXT_SIZE			320
#define LONG_OMF_DELTA			3

#define INDIRECT_NEST_LIMIT		10

#define NEW_FIXUPP_SIZE			1024

#define CV_TEMP_SIZE			(9 * 1024)
#define TEMP_SIZE			1024

#define FILENAME_HASH_SIZE		0xFB
#define THEADR_HASH_SIZE		61
#define VIRDEF_MCD_HASH_SIZE		0xFB

#define CASE_SENSITIVE		0
#define MAX_RECORD_LEN		(1024+64+6*1024)	// FOR BORLAND
#define SLRIB			0		// NOT OPTLIB
#define OPTLIB			0

#define MAX_LEDATA_LEN		(2 * 1024)

#define BLOCK_BASE		sizeof(FA_BASE_S)	// STARTING OFFSET FOR FAR BLOCKS (FIRST DWORD IS USAGE COUNT, NEXT IS NEXT_PTR)
					// **** FARCALLTRANSLATE MAY NOT HANDLE CHANGE CORECTLY ****

#define EMS_XMS_DELTA		(1024/(PAGE_SIZE/(1024))*2)

#define N_R_THREADS		4		// # OF OPEN-READ THREADS
#define N_W_THREADS		4

;#define PHYS_TABLE_SIZE 	4		// # OF 16K BLOCKS RELEASED LOCALLY OS/2

;#define MAX_VECTORS		((32*1024)/VECTOR_SIZE*2)

#define M1		-1

typedef struct FARCALL_HEADER_TYPE
{
    unsigned _FC_BLOCK_BASE;
    unsigned _FC_NEXT_FARCALL;
    unsigned _FC_LENGTH;
    unsigned _FC_SEGMOD_GINDEX;
} FARCALL_HEADER_TYPE;

typedef struct TPTR_STRUCT
{
    unsigned _TP_FLAGS;
    unsigned _TP_HASH;
    unsigned _TP_LENGTH;
    unsigned char _TP_TEXT[SYMBOL_TEXT_SIZE];
} TPTR_STRUCT;

#define PRIME_128		0x07F
#define PRIME_256		0x0FB
#define PRIME_512		0x1FD
#define PRIME_1K		0x3FD
#define PRIME_2K		0x7F7
#define PRIME_4K		0xFFD

#define SEGMENT_HASH_SIZE	0xFFF
#define SEGMENT_HASH_DXLIMIT	0xFFF

typedef struct LARRAY_STRUCT
{
    unsigned _LARRAY_NEXT; 	// NEXT PLACE TO STORE ENTRY
    unsigned _LARRAY_LIMIT;	// # OF VALID ENTRIES IN TABLE
    unsigned _LARRAY_COUNT;	// # LEFT TO ALLOCATE THIS BLOCK
    unsigned _LARRAY_NEXT_BASE;
    unsigned _LARRAY_BASES[(32 * 1024)/(PAGE_SIZE/4)];	// POINTS TO DGROUP 512-BYTE ALLOCATION
} LARRAY_STRUCT;

#if 0
STD_PTR_S	STRUC				;USED BY LIBRARIES, SOON MASTER GROUPS, SEGMENTS, CLASSES, POSSIBLY EVEN SYMBOLS, OTHERS

_STD_BASE_NEXT 	DD	?	;		NEXT PLACE TO STORE BLOCK POINTER
_STD_NEXT 	DD	?	;		NEXT PLACE TO STORE PTR
_STD_LIMIT	DD	?	;		# OF VALID ENTRIES IN TABLE
_STD_COUNT	DD	?	;		# LEFT TO ALLOCATE THIS BLOCK
_STD_ALLOC_ROUTINE	DCA	?	;	ALLOCATE MEMORY FOR PTRS
_STD_TYPE_TEXT	DD	?
_STD_INSTALL_ROUTINE	DCA	?	;	INSTALL NEXT ENTRY INTO TABLE
_STD_INSTALL_RANDOM_ROUTINE	DCA	?	;
_STD_AX_TO_DSSI	DCA	?	;		CONVERT AX TO PTR IN DS:SI PHYSICAL
_STD_AX_TO_ESDI	DCA	?	;		CONVERT AX TO PTR IN ES:DI PHYSICAL
if	0	;fgh_os2
_STD_AX_TO_DSSI_THREAD	DCA	?	;	CONVERT FROM THREAD (SS!=DGROUP)
endif
_STD_EAX_TO_EBX	DD	?
_STD_PTRS	DD	16 DUP(?)	;	INITIALLY PTRS, THEN PTRS TO BLOCKS, THEN PTR TO MASTER BLOCK

STD_PTR_S	ENDS


PAR_PTR_S	STRUC		;USED FOR PARALLEL STRUCTURES

_PAR_PTRS_PTR	DD	?	;ADDRESS OF BLOCK POINTERS
_PAR_TO_DSSI	DCA	?
_PAR_TO_ESDI	DCA	?
_PAR_SHIFTS	DW	?	;
_PAR_MASK	DW	?	;
_PAR_BLOCKS	DW	?	;# OF BLOCKS MAX
_PAR_LIMIT	DW	?	;FOR RANDOM INSTALLERS

PAR_PTR_S	ENDS


;CONVERT_PAR_GINDEX_AX_DSSI	MACRO	XX
;
;		LEA	SI,XX
;		CALL	DGROUP:[SI]._PAR_TO_DSSI
;
;		ENDM

;CONVERT_PAR_GINDEX_AX_ESDI	MACRO	XX
;
;		LEA	DI,XX
;		CALL	DGROUP:[DI]._PAR_TO_ESDI
;
;		ENDM


FA_S		STRUC

FA_PTR		DD	?
FA_CNT		DD	?
FA_BASE		DD	?

FA_S		ENDS

if	0;fgh_os2

SEMAPHORE_STRUCT	STRUC

_SEM_ITSELF	DD	?
_SEM_COUNTER	DW	?
_SEM_NOTHING	DW	?

SEMAPHORE_STRUCT	ENDS

endif

PLTYPES 	RECORD	SEG_OVERLAYABLE:1,SECTION_ASSIGNED:1,LEVEL_0_SECTION:1


LDATA_HEADER_TYPE STRUC

_LD_BLOCK_BASE	DD	?	;ADDRESS AT START OF PAGE_SIZE BLOCK
_LD_NEXT_LDATA	DD	?	;NEXT LDATA THIS SEGMOD, OR FIXUPP
_LD_LENGTH	DW	?	;LENGTH OF DATA RECORD
_LD_TYPE	DB	?	;LEDATA, FIXUPP, LIDATA, 32 VS 16 BIT,FR, ETC
		DB	?
_LD_OFFSET	DD	?	;IF DATA, THIS IS SEGMOD OFFSET

LDATA_HEADER_TYPE ENDS


FIXUPP_HEADER_TYPE STRUC

_FH_BLOCK_BASE	DD	?	;ADDRESS AT START OF PAGE_SIZE BLOCK
_FH_NEXT_FIXUPP DD	?

_FH_LENGTH	DW	?
_FH_TYPE	DB	?
_FH_XTRA	DB	?

FIXUPP_HEADER_TYPE ENDS


FORREF_HEADER_TYPE STRUC

_FR_BLOCK_BASE	DD	?	;ADDRESS AT START OF PAGE_SIZE BLOCK
_FR_NEXT_FORREF DD	?

_FR_LENGTH	DW	?
_FR_TYPE	DB	?
_FR_XTRA	DB	?	;TYPE OF DATA TO FIXUPP

FORREF_HEADER_TYPE ENDS

#endif

typedef struct LINNUM_HEADER_TYPE
{
    unsigned _LN_BLOCK_BASE;
    unsigned _LN_NEXT_LINNUM;	// NEXT LINNUM RECORD THIS SEG_SRC_MOD

    unsigned short _LN_LENGTH;	// LENGTH AFTER HEADER
    unsigned char _LN_TYPE;	// 16 OR 32 BIT
    unsigned char reserved;

    unsigned _LN_SRC_GINDEX;	// SOURCE FILE INDEX FOR THESE LINES
} LINNUM_HEADER_TYPE;

#if 0

FARCALL_HEADER_TYPE STRUC

_FC_BLOCK_BASE		DD	?
_FC_NEXT_FARCALL	DD	?
_FC_LENGTH		DD	?
_FC_SEGMOD_GINDEX	DD	?

FARCALL_HEADER_TYPE ENDS


LINK_TARGETS_STRUC	STRUC

_LT_SEG_CLASS	DD	?
_LT_NEXT	DD	?
_LT_TYPE	DW	?

LINK_TARGETS_STRUC	ENDS

SSSS		STRUC

ADDER		DW	?
AMASK		DW	?

SSSS		ENDS
#endif

#define CMDLINE_PTR	CURN_INPTR
#define CMDLINE_LENGTH	CURN_COUNT

#if 0
MAP_RECORD	RECORD	MAP_A:1,MAP_E:1,MAP_N:1,MAP_M:1,MAP_S:1,MAP_L:1,MAP_D:1

if	fg_segm

FLG0C	RECORD	APPTYPE:1,\	;0=PROGRAM, 1=DLL
		APP??:1,\	;UNKNOWN
		APPERRORS:1,\	;ERRORS DURING LINK
		APP???:3,\	;UNKNOWN
		APPWINFLAGS:2,\ ;WINDOWAPI, WINDOWCOMPAT, NOTWINDOWCOMPAT
		APPFLOATS:1,\	;FLOATS USED?
		APP386:1,\	;386 INSTRUCTIONS
		APP286:1,\	;286 INSTRUCTIONS
		APP86:1,\	;8086-ONLY
		APPPROT:1,\	;PROTMODE APP
		APPINSTANCE:1,\ ;INSTANCE DATA
		APPMULTI:1,\	;MULTIPLE DATA (NONSHARED)
		APPSOLO:1	;SOLO DATA (SHARED)

endif

OFFS		EQU	WORD PTR 0
SEGM		EQU	WORD PTR 2
PHYS		EQU	WORD PTR 4


GLOBALSEM_STRUCT	STRUC

_SEM_ITSELF	DD	?
_SEM_COUNTER	DD	?

GLOBALSEM_STRUCT	ENDS


if	fg_virt

EMS_STRUC	STRUC

_EMS_LENGTH	DD	?	;LENGTH OF REGION
_EMS_SRC_TYPE	DB	?	;0 = CONVENTIONAL, 1 = EMS
_EMS_SRC_HANDLE DW	?	;
_EMS_SRC_OFFSET DW	?
_EMS_SRC_SEG	DW	?
_EMS_DST_TYPE	DB	?
_EMS_DST_HANDLE DW	?
_EMS_DST_OFFSET DW	?
_EMS_DST_SEG	DW	?

EMS_STRUC	ENDS

EMS_XMS_STRUCT	STRUC

_EX_PREV_BLOCK	DW	?
_EX_NEXT_BLOCK	DW	?
_EX_TO_LOG	DW	?

EMS_XMS_STRUCT	ENDS

XMS_STRUC	STRUC

XMS_PAGES	DW	?	;# OF PAGES FOR THIS GUY
XMS_HANDLE	DW	?	;HANDLE FOR THIS GUY

XMS_STRUC	ENDS

endif

ALLOC_STRUC	STRUC
_A_PTR		DW	?
_A_RELEASED	DW	?
ALLOC_STRUC	ENDS

GET_OMF_NAME_LENGTH	MACRO
		LOCAL	L1

		EXTERNDEF	xTOO_LONG:PROC

                XOR     EAX,EAX

                MOV     AL,BPTR [ESI]
                INC     ESI

                CMP     AL,-1
                JNZ      L1

                CMP     BPTR [ESI],AH
                JNZ     L1

                MOV     AX,word ptr[ESI+1]
                ADD     ESI,3

                CMP     EAX,SYMBOL_TEXT_SIZE
                JA      xTOO_LONG
L1:
		ENDM

GET_OMF_NAME_LENGTH_EAX	MACRO
		LOCAL	L1

		EXTERNDEF	xTOO_LONG:PROC

		MOV	ECX,EAX
		MOV	AL,BPTR [EAX]

		INC	ECX
		AND	EAX,0FFH

		CMP	AL,-1
		JNZ	L1

		CMP	BPTR [ECX],AH
		JNZ	L1

		MOV	AX,[ECX+1]
		ADD	ECX,3

		CMP	EAX,SYMBOL_TEXT_SIZE
		JA	xTOO_LONG

L1:
		ENDM


GET_NAME_HASH	MACRO	;SYM_TOO_LONG
;;GET NAME FROM ESI INTO SYMBOL_TPTR IN EDI
		;;ES=SS=DGROUP
		;;DS:SI IS SOURCE TEXT, SYMBOL_LENGTH&SYMBOL_TEXT ARE DESTIN
		GET_OMF_NAME_LENGTH
		MOV	[EDI]._TP_LENGTH,EAX	;;STORE SYMBOL LENGTH
		LEA	EDI,[EDI]._TP_TEXT
		CALL	OPTI_MOVE		;;GO THRU JUMP TABLE U/L

		ENDM

GET_NAME_HASHD	MACRO
;;GET NAME FROM DS:SI INTO SYMBOL_TEXT IN DATA SEGMENT
		;;ES=SS=DGROUP
		;;DS:SI IS SOURCE TEXT, SYMBOL_LENGTH&SYMBOL_TEXT ARE DESTIN
		MOV	EAX,[ESI]		;;SYMBOL LENGTH
		ADD	ESI,4
		MOV	[EDI],EAX
		ADD	EDI,4
		CALL	OPTI_MOVE		;;GO THRU JUMP TABLE U/L
		ENDM

INSTALL_POINTER_LINDEX	MACRO	XX		;;INSTALL AX:BX=PTR, RETURN AX=LINDEX

		PUSH	ECX
		MOV	ECX,OFF XX
		EXTERNDEF	LOCAL_PTR_INSTALL:PROC
		CALL	LOCAL_PTR_INSTALL
		POP	ECX
		ENDM

INSTALL_POINTER_GINDEX	MACRO	XX		;;INSTALL AX:BX=PTR, RETURN AX=GINDEX
;;		IFIDN	<_FILE_LIST_GARRAY>,<XX>
;;		ELSEIFIDN	<AREA_GARRAY>,<XX>
		IFIDNI	<XX>,<CV_LTYPE_GARRAY>
		EXTERNDEF	INSTALL_LTYPE_POINTER:PROC
		CALL	INSTALL_LTYPE_POINTER
		ELSEIFIDNI	<XX>,<CV_GTYPE_GARRAY>
		EXTERNDEF	INSTALL_GTYPE_POINTER:PROC
		CALL	INSTALL_GTYPE_POINTER
		ENDIF
		ENDM


INSTALL_POINTER_RANDOM_GINDEX	MACRO	X
		;
		;EAX IS POINTER TO STORE OFF GINDEX (ECX)
		;
		PUSH	ECX
		DEC	ECX

		PUSH	EDX
		MOV	EDX,ECX

		SHR	EDX,PAGE_BITS-2
		AND	ECX,PAGE_MASK SHR 2

		MOV	EDX,X[EDX*4]._STD_PTRS

		MOV	DPTR [EDX+ECX*4],EAX
		POP	EDX

		POP	ECX

		ENDM


INSTALL_GINDEX_LINDEX	MACRO	XX		;;INSTALL AX=GINDEX, RETURN AX=LINDEX
		IFIDN	<LNAME_LARRAY>,<XX>
		.ERR
		ELSE
		PUSH	ECX
		MOV	ECX,OFF XX
		EXTERNDEF	LOCAL_PTR_INSTALL:PROC
		CALL	LOCAL_PTR_INSTALL
		POP	ECX
		ENDIF
		ENDM

NEW_ARRAY	MACRO	XX,YY
		PUSH	BX
		PUSH	AX
		LEA	BX,XX
		MOV	AX,YY
		EXTERNDEF	DO_NEW_ARRAY:PROC
		CALL	DO_NEW_ARRAY
		POPM	AX,BX
		ENDM

INIT_ARRAY	MACRO	XX,SIZE
		MOV	AX,XX&_ARRAY.SP_BASE
;;		ADD	AX,SIZE
		MOV	XX&_ARRAY.SP_NEXT,AX
		ENDM

NEXT_INDEXI	MACRO
		;;THIS MACRO ASSUMES RANDOM INDEX SIZE
		LOCAL	LOC1

		XOR	EAX,EAX
		MOV	AL,[ESI]
		INC	ESI
		TEST	AL,AL
		JNS	LOC1
		MOV	AH,AL
		MOV	AL,[ESI]
		INC	ESI
		AND	AH,7FH
LOC1:
		ENDM

NEXT_INDEX	MACRO	ZZ
		XOR	EAX,EAX

		MOV	AL,[ESI]
		INC	ESI

		TEST	AL,AL
		JS	ZZ
ZZ&_RET:
		ENDM

DOLONG		MACRO	ZZ
ZZ:
		MOV	AH,AL
		MOV	AL,[ESI]

		INC	ESI
		AND	AH,7FH

		JMP	ZZ&_RET
		ENDM

CONVERT_MYCOMDAT_EAX_ECX	MACRO
		EXTERNDEF	MYCOMDAT_SEARCH:PROC
		CALL	MYCOMDAT_SEARCH
		ENDM


CONVERT		MACRO	XX,YY,ZZ
		IFIDNI	<ZZ>,<CV_LTYPE_GARRAY>
		CONVERT_TYPE	XX,YY,ZZ

		ELSEIFIDNI	<ZZ>,<CV_GTYPE_GARRAY>
		CONVERT_TYPE	XX,YY,ZZ

		ELSE

		MOVV	XX,YY

		ENDIF

		ENDM


CONVERT_TYPE	MACRO	XX,YY,ZZ

		IFIDNI	<XX>,<YY>
		.ERR
		ENDIF

		PUSH	YY
		DEC	YY

		MOV	XX,YY

		SHR	XX,PAGE_BITS-2
		AND	YY,PAGE_MASK SHR 2

		MOV	XX,ZZ[XX*4]._STD_PTRS

		MOV	XX,DPTR [XX+YY*4]
		POP	YY

		ENDM


MOVV		MACRO	XX,YY
		IFIDN	<XX>,<YY>
		ELSE
		MOV	XX,YY
		ENDIF
		ENDM


;CONVERT_GINDEX_AX_DSSI	MACRO	XX
;
;		PUSH	ECX
;		MOV	ECX,EAX
;		PUSH	EAX
;		SHR	EAX,14
;		AND	ECX,16K-1
;		MOV	ESI,XX[EAX*4]._STD_PTRS
;		POP	EAX
;		MOV	ESI,DPTR [ESI+ECX*4]
;		POP	ECX
;
;		ENDM
;
;CONVERT_GINDEX_EAX_EBX	MACRO	XX
;
;		PUSH	ECX
;		MOV	ECX,EAX
;		PUSH	EAX
;		SHR	EAX,14
;		AND	ECX,16K-1
;		MOV	EBX,XX[EAX*4]._STD_PTRS
;		POP	EAX
;		MOV	EBX,DPTR [EBX+ECX*4]
;		POP	ECX
;
;		ENDM


;CONVERT_GINDEX_EAX_ECX	MACRO	XX
;
;		PUSH	EBX
;		MOV	EBX,EAX
;		PUSH	EAX
;		SHR	EAX,14
;		AND	EBX,16K-1
;		MOV	ECX,XX[EAX*4]._STD_PTRS
;		POP	EAX
;		MOV	ECX,DPTR [ECX+EBX*4]
;		POP	EBX
;
;		ENDM
;
;CONVERT_GINDEX_EAX_EAX	MACRO	XX
;
;		PUSH	ECX
;		MOV	ECX,EAX
;		SHR	EAX,14
;		AND	ECX,16K-1
;		MOV	EAX,XX[EAX*4]._STD_PTRS
;		MOV	EAX,DPTR [EAX+ECX*4]
;		POP	ECX
;
;		ENDM

;TCONVERT_GINDEX_AX_DSSI	MACRO	XX
;		CAPTURE	TCONVERT_SEM
;		MOV	ESI,OFF XX
;		CALL	XX._STD_AX_TO_DSSI_THREAD
;		RELEASE	TCONVERT_SEM
;		ENDM

;TSCONVERT_GINDEX_AX_DSSI	MACRO	XX
;		MOV	ESI,OFF XX
;		CALL	XX._STD_AX_TO_DSSI_THREAD
;		ENDM

;CONVERT_GINDEX_AX_ESDI	MACRO	XX
;
;		PUSH	ECX
;		MOV	ECX,EAX
;		PUSH	EAX
;		SHR	EAX,14
;		AND	ECX,16K-1
;		MOV	EDI,XX[EAX*4]._STD_PTRS
;		POP	EAX
;		MOV	EDI,DPTR [EDI+ECX*4]
;		POP	ECX
;
;		ENDM


CONVERT_LINDEX_EAX_EAX	MACRO	ARRAY_ID,REG

		EXTERNDEF	INDEX_RANGE:PROC

		DEC	EAX
		MOV	REG,ARRAY_ID._LARRAY_LIMIT

		CMP	REG,EAX
		JBE	INDEX_RANGE

		MOV	REG,EAX

		SHR	EAX,12
		AND	REG,4K-1

		MOV	EAX,ARRAY_ID[EAX*4]._LARRAY_BASES

		MOV	EAX,DPTR [EAX+REG*4]
		ENDM


P1ONLY_POOL_ALLOC	MACRO	XX		;;USED ONLY ON PASS1, THEN CAN BE DELETED
		EXTERNDEF	P1ONLY_POOL_GET:PROC
		CALL	P1ONLY_POOL_GET
		ENDM

SECTION_POOL_ALLOC	MACRO	XX
		;;ALREADY DWORD ALIGNED...
		;;RETURN ES:DI = PHYS, AX IS LOGICAL
		EXTERNDEF	SECTION_POOL_GET:PROC
		CALL	SECTION_POOL_GET

		ENDM

TILLP2_POOL_ALLOC	MACRO	XX		;;PROBABLY NOT NEEDED AGAIN TILL PASS2
		;;ALREADY DWORD ALIGNED...
		;;RETURN ES:DI = PHYS, AX IS LOGICAL
		EXTERNDEF	TILLP2_POOL_GET:PROC
		CALL	TILLP2_POOL_GET

		ENDM

TILLMIDDLE_POOL_ALLOC	MACRO	XX		;;PROBABLY NOT NEEDED AGAIN TILL MIDDLE
		;;ALREADY DWORD ALIGNED...
		;;RETURN ES:DI = PHYS, AX IS LOGICAL
		EXTERNDEF	TILLMIDDLE_POOL_GET:PROC
		CALL	TILLMIDDLE_POOL_GET

		ENDM

CLASS_POOL_ALLOC	MACRO
		;;ALREADY DWORD ALIGNED...
		;;RETURN ES:DI = PHYS, AX IS LOGICAL
		EXTERNDEF	CLASS_POOL_GET:PROC
		CALL	CLASS_POOL_GET

		ENDM

SEGMENT_POOL_ALLOC	MACRO
		;;ALREADY DWORD ALIGNED...
		;;RETURN ES:DI = PHYS, AX IS LOGICAL
		EXTERNDEF	SEGMENT_POOL_GET:PROC
		CALL	SEGMENT_POOL_GET

		ENDM

SEGMOD_POOL_ALLOC	MACRO
		;;ALREADY DWORD ALIGNED...
		;;RETURN ES:DI = PHYS, AX IS LOGICAL
		EXTERNDEF	SEGMOD_POOL_GET:PROC
		CALL	SEGMOD_POOL_GET

		ENDM

MODULE_POOL_ALLOC	MACRO
		;;ALREADY DWORD ALIGNED...
		;;RETURN ES:DI = PHYS, AX IS LOGICAL
		EXTERNDEF	MODULE_POOL_GET:PROC
		CALL	MODULE_POOL_GET

		ENDM

GROUP_POOL_ALLOC	MACRO
		;;ALREADY DWORD ALIGNED...
		;;RETURN ES:DI = PHYS, AX IS LOGICAL
		EXTERNDEF	GROUP_POOL_GET:PROC
		CALL	GROUP_POOL_GET

		ENDM

SSYM_POOL_ALLOC MACRO	XX
		;;ALREADY DWORD ALIGNED...
		;;RETURN ES:DI = PHYS, AX IS LOGICAL
		EXTERNDEF	SSYM_POOL_GET:PROC
		CALL	SSYM_POOL_GET

		ENDM

TEXT_POOL_ALLOC MACRO	XX			;USED FOR LNAME TEXT,
		;;ALREADY DWORD ALIGNED...
		;;RETURN ES:DI = PHYS, AX IS LOGICAL
		EXTERNDEF	TEXT_POOL_GET:PROC
		CALL	TEXT_POOL_GET
		ENDM

LTEXT_POOL_ALLOC MACRO	XX			;USED FOR LOCAL LNAME TEXT,
		;;ALREADY DWORD ALIGNED...
		;;RETURN ES:DI = PHYS, AX IS LOGICAL
		EXTERNDEF	LTEXT_POOL_GET:PROC
		CALL	LTEXT_POOL_GET
		ENDM

TEXT_POOL_ALLOC_FIX	MACRO	XX
		ENDM

SYM_POOL_ALLOC_FIX	MACRO	XX
		ENDM

SSYM_POOL_ALLOC_FIX	 MACRO	 XX
		ENDM

HASHDIV		MACRO	XX

		DIV	XX

;;		MOV	EDX,EAX
;;
;;		SHR	EAX,16
;;
;;		XOR	EAX,EDX
;;		MOV	EDX,XX
;;
;;		XOR	AL,AH
;;		DEC	EDX
;;
;;		AND	EDX,EAX
;;
;;		DIV	WPTR XX

		ENDM

OPTIMOVE	MACRO
		LOCAL	L1,L2

		CMP	ECX,8
		JB	L1
		PUSH	ECX
		SHR	ECX,2
		REP	MOVSD
		POP	ECX
		AND	ECX,3
		JZ	L2
L1:
		REP	MOVSB
L2:
		ENDM

OPTI_MOVSB	EQU	OPTIMOVE

;OPTI_MOVSW_386	MACRO			;;WORD MOVE LARGE ENOUGH TO GET ADVANTAGE FROM 386
;		REP	MOVSW		;;SO WHAT FOR NOW
;		ENDM

;OPTI_MOVSW	MACRO
;		LOCAL	L1
;		SHR	ECX,1
;		REP	MOVSD		;;USE SHR CX,1 REP MOVSD ON 386
;		JNC	L1
;		MOVSW
;L1:
;		ENDM

OPTI_MOVSD	MACRO
		REP	MOVSD
		ENDM

OPTI_STOSD	MACRO
;		LOCAL	L1,L2
;		CMP	ECX,8
;		JB	L1
;
;		PUSH	ESI
;		MOV	[EDI],EAX
;
;		MOV	ESI,EDI
;		ADD	EDI,4
;
;		DEC	ECX
;
;		REP	MOVSD
;
;		POP	ESI
;		JMP	L2
;
;L1:
		REP	STOSD
;L2:
		ENDM


;OPTI_STOSW	MACRO
;		LOCAL	L1
;		SHR	ECX,1
;		REP	STOSD
;		JNC	L1
;		STOSW
;L1:
;		ENDM

OPTI_STOSB	MACRO
		LOCAL	L1,L2

		CMP	ECX,8
		JB	L1
		PUSH	ECX
		SHR	ECX,2
		REP	STOSD
		POP	ECX
		AND	ECX,3
		JZ	L2
L1:
		REP	STOSB
L2:
		ENDM

SKIP_INDEX	MACRO

		MOV	AL,[ESI]
		INC	ESI
		ROL	AL,1
		SBB	EAX,EAX
		SUB	ESI,EAX
		ENDM

SETT	MACRO	XX,YY
;;	OR	BPTR (XX/8)-80H[BP],1 SHL (XX MOD 8)
	EXTERNDEF	XX:BYTE
	IFB	<YY>
	MOV	XX,-1
	ELSE
	MOV	XX,YY
	ENDIF
	ENDM

GETT	MACRO	XX,YY
	EXTERNDEF	YY:BYTE
	MOV	XX,YY
	ENDM

BITT	MACRO	XX,YY
	EXTERNDEF	XX:BYTE
	IFB	<YY>
	TEST	XX,-1
	ELSE
	CMP	XX,YY
	ENDIF
	ENDM

RESS	MACRO	XX,YY
;;	AND	BPTR (XX/8)-80H[BP],NOT (1 SHL (XX MOD 8))
	EXTERNDEF	XX:BYTE
	IFB	<YY>
	MOV	XX,0
	ELSE
	MOV	XX,YY
	ENDIF
	ENDM

;BITT2	MACRO	XX
;	TEST	BPTR (XX/8)[STACK_VARIABLES],1 SHL (XX MOD 8)
;	ENDM

	if	fg_virt

LOCKIT		MACRO
		EXTERNDEF	LOCK_BLOCK:PROC
		CALL	LOCK_BLOCK
		ENDM

UNLOCKIT		MACRO
		EXTERNDEF	UNLOCK_BLOCK:PROC
		CALL	UNLOCK_BLOCK
		ENDM

MCONVERT_BX_TO_DX	MACRO
		EXTERNDEF	CONVERT_BX_TO_DX:PROC
		CALL	CONVERT_BX_TO_DX
		ENDM

CONV_ES 	MACRO
		EXTERNDEF	CONVERT_ES_TO_ES:PROC
		CALL	CONVERT_ES_TO_ES
		ENDM

CONV_ES_AX		MACRO
		EXTERNDEF	CONVERT_ES_TO_ES:PROC
		PUSH	AX
		CALL	CONVERT_ES_TO_ES
		POP	AX
		ENDM

CONV_DS 	MACRO

		EXTERNDEF	CONVERT_DS_TO_DS:PROC
		CALL	CONVERT_DS_TO_DS

		ENDM

VIRT_?		EQU

	else

LOCKIT		MACRO
		ENDM
UNLOCKIT	MACRO
		ENDM
MCONVERT_BX_TO_DX	MACRO
		MOV	DX,BX
		ENDM
CONV_ES 	MACRO
		ENDM
CONV_ES_AX	MACRO
		ENDM
CONV_DS 	MACRO
		ENDM

VIRT_?		EQU	<;>

	endif

if	fg_sym_virt

SYM_ALIGN	EQU	<ALIGN	4,,1>

SYM_?		EQU			;ALLOW THIS INSTRUCTION

NOT_SYM_?	EQU	<;>

SYM_CONV_DS	MACRO

		EXTERNDEF	CONVERT_DS_TO_DS:PROC
		CALL	CONVERT_DS_TO_DS

		ENDM

SYM_LOCKIT	MACRO
		EXTERNDEF	SYM_LOCK_BLOCK:PROC
		CALL	SYM_LOCK_BLOCK
		ENDM

SYM_UNLOCKIT	MACRO
		EXTERNDEF	SYM_UNLOCK_BLOCK:PROC
		CALL	SYM_UNLOCK_BLOCK
		ENDM

SYM_CONV_ES	MACRO

		EXTERNDEF	CONVERT_ES_TO_ES:PROC
		CALL	CONVERT_ES_TO_ES

		ENDM

SYM_CONV_DS_AX	MACRO

		EXTERNDEF	CONVERT_DS_TO_DS:PROC
		PUSH	AX
		CALL	CONVERT_DS_TO_DS
		POP	AX

		ENDM

SYM_CONV_ES_AX	MACRO

		EXTERNDEF	CONVERT_ES_TO_ES:PROC
		PUSH	AX
		CALL	CONVERT_ES_TO_ES
		POP	AX

		ENDM

else

SYM_ALIGN	EQU	<ALIGN	4>

SYM_?		EQU	<;>

NOT_SYM_?	EQU

SYM_CONV_DS	EQU	<;>

SYM_CONV_ES	EQU	<;>

SYM_LOCKIT	EQU	<;>
SYM_UNLOCKIT	EQU	<;>

SYM_CONV_DS_AX	EQU	<;>

SYM_CONV_ES_AX	EQU	<;>

endif

if fgh_prot

PUSHI		MACRO	XX,Y,Z,A,B,C,D,E,F,G
		PUSH	Y Z A B C D E F G
		ENDM

ROLI		MACRO	XX,Y,Z,A,B,C,D
		ROL	XX,Y Z A B C D
		ENDM

RORI		MACRO	XX,Y,Z,A,B,C,D
		ROR	XX,Y Z A B C D
		ENDM

SHRI		MACRO	XX,Y,Z,A,B,C,D
		SHR	XX,Y Z A B C D
		ENDM

SHLI		MACRO	XX,Y,Z,A,B,C,D
		SHL	XX,Y Z A B C D
		ENDM

RCRI		MACRO	XX,Y,Z,A,B,C,D
		RCR	XX,Y,Z,A,B,C,D
		ENDM

else

PUSHI		MACRO	XX,Y,Z,A,B,C,D,E,F,G
		MOV	XX,Y Z A B C D E F G
		PUSH	XX
		ENDM

ROLI		MACRO	XX,Y,Z,A,B,C
		IF	Y Z A B C GT 4
		PUSH	CX
		MOV	CL,Y Z A B C
		ROL	XX,CL
		POP	CX
		ELSE
		REPT	Y Z A B C
		ROL	XX,1
		ENDM
		ENDIF
		ENDM

RORI		MACRO	XX,Y,Z,A,B,C
		IF	Y Z A B C GT 4
		PUSH	CX
		MOV	CL,Y Z A B C
		ROR	XX,CL
		POP	CX
		ELSE
		REPT	Y Z A B C
		ROR	XX,1
		ENDM
		ENDIF
		ENDM

SHRI		MACRO	XX,Y,Z,A,B,C
		IF	Y Z A B C GT 4
		PUSH	CX
		MOV	CL,Y Z A B C
		SHR	XX,CL
		POP	CX
		ELSE
		REPT	Y Z A B C
		SHR	XX,1
		ENDM
		ENDIF
		ENDM

SHLI		MACRO	XX,Y,Z,A,B,C
		IF	Y Z A B C GT 4
		PUSH	CX
		MOV	CL,Y Z A B C
		SHL	XX,CL
		POP	CX
		ELSE
		REPT	Y Z A B C
		ADD	XX,XX
		ENDM
		ENDIF
		ENDM

RCRI		MACRO	XX,Y,Z,A,B,C
		IF	Y Z A B C GT 4
		PUSH	CX
		MOV	CL,Y Z A B C
		RCR	XX,CL
		POP	CX
		ELSE
		REPT	Y Z A B C
		RCR	XX,1
		ENDM
		ENDIF
		ENDM

endif

if	fgh_anythreads

CAPTURE		MACRO	XX		;CAPTURE THIS SEMAPHORE

		PUSH	EAX

		push	ECX
		push	EDX
		push	OFF XX
		CALL	_capture_eax
		add	ESP,4
		pop	EDX
		pop	ECX

		;MOV	EAX,OFF XX
		;CALL	CAPTURE_EAX

		POP	EAX

		ENDM

RELEASE		MACRO	XX		;RELEASE THIS SEMAPHORE

		PUSH	EAX

		push	ECX
		push	EDX
		push	OFF XX
		call	_release_eax
		add	ESP,4
		pop	EDX
		pop	ECX

		;MOV	EAX,OFF XX
		;CALL	RELEASE_EAX

		POP	EAX

		ENDM

RELEASE_BUMP	MACRO	XX		;RELEASE THIS SEMAPHORE

		PUSH	EAX

		push	ECX
		push	EDX
		push	OFF XX
		call	_release_eax_bump
		add	ESP,4
		pop	EDX
		pop	ECX

		;MOV	EAX,OFF XX
		;CALL	RELEASE_EAX_BUMP

		POP	EAX

		ENDM

else

CAPTURE		MACRO	XX
		ENDM

RELEASE		MACRO	XX
		ENDM

RELEASE_BUMP	MACRO	XX
		ENDM

endif

INT21		MACRO
if	fgh_dpmi
		EXTERNDEF	INT21_ROUTINE:PROC
		CALL	INT21_ROUTINE
elseif fgh_win
		CALL	DOS3CALL
elseif	fgh_dosx
		INT	21H
		CLD
else
		INT	21H
		CLD
endif
		ENDM

INT31		MACRO
if	fgh_dpmi
if	debug
		EXTERNDEF	INT31_ROUTINE:PROC
		CALL	INT31_ROUTINE
else
		INT	31H
		CLD
endif
else
		.ERR
endif
		ENDM

DOS		MACRO
		EXTERNDEF	DOS_ROUTINE:PROC
		CALL	DOS_ROUTINE
		ENDM

if	fgh_win32dll

YIELD		MACRO

		EXTERNDEF	REPORT_PROGRESS:PROC
		CALL	REPORT_PROGRESS

		ENDM

SUSPEND_CANCEL	MACRO
		ENDM

RESUME_CANCEL	MACRO
		ENDM
else

YIELD		MACRO
		ENDM

SUSPEND_CANCEL	MACRO
		ENDM

RESUME_CANCEL	MACRO
		ENDM
endif

DO_FILE_ALIGN_EAX	MACRO

		ADD	EAX,SEG_PAGE_SIZE_M1

		AND	EAX,NOT_SEG_PAGE_SIZE_M1

		ENDM


CONVERT_GINDEX_BXAX_DSSI	MACRO	XX
		EXTERNDEF	STD32_BXAX_TO_DSSI:PROC
		LEA	SI,XX
		CALL	STD32_BXAX_TO_DSSI
		ENDM

CONVERT_GINDEX_BXAX_ESDI	MACRO	XX
		EXTERNDEF	STD32_BXAX_TO_ESDI:PROC
		LEA	DI,XX
		CALL	STD32_BXAX_TO_ESDI
		ENDM

INSTALL_POINTER_GINDEX32	MACRO	XX
		EXTERNDEF	STD32_INSTALL_PTR_ROUTINE:PROC
		PUSH	SI
		LEA	SI,XX
		CALL	STD32_INSTALL_PTR_ROUTINE
		POP	SI
		ENDM

STD32_PTR_S		STRUC		;USED BY TDBG_NAMES,

_STD32_BASE 		DD	?	;PTR TO MASTER BLOCK OF POINTERS
_STD32_NEXT 		DD	?	;NEXT PLACE TO STORE PTR
_STD32_LIMIT		DD	?	;# OF VALID ENTRIES IN TABLE
_STD32_BASES		DD	?	;PLACE TO STORE NEXT BASE PTR
_STD32_ALLOCATE		DCA	?	;ALLOCATE MEMORY FOR THIS DATA TYPE
_STD32_COUNT		DW	?	;# LEFT TO ALLOCATE THIS BLOCK
_STD32_STUFF_PTR	DW	?	;

STD32_PTR_S		ENDS

TO_UPPER		MACRO
			LOCAL	L1
		CMP	AL,'a'
		JC	L1
		CMP	AL,'z'+1
		JNC	L1
		SUB	AL,20H
L1:
		ENDM
#endif

#endif
